/***************************************************************
*
* M3D_FLOAT2INT.HPP
*
* Float-2-int conversions
***************************************************************/


/***************************************************************
* m3dCONV_POS48::m3dCONV_POS48()
*
***************************************************************/
template <class _CONV>
_m3dCONV_POS48<_CONV>::_m3dCONV_POS48 (void) 
{
   // note - this is NOT a virtual call
   Init();
}

/***************************************************************
* m3dCONV_POS48::Init()
*
***************************************************************/
template <class _CONV>
void _m3dCONV_POS48<_CONV>::Init (void) 
{
   convX17.Init(17, -6000.f, 6000.f);
   convY14.Init(14, -3000.f, 3000.f);
   convZ17.Init(17, -6000.f, 6000.f);
   return;
}

/***************************************************************
* _m3dCONV_POS48::Init()
*
***************************************************************/
template <class _CONV>
void _m3dCONV_POS48<_CONV>::Init (m3dBOX *pBox) 
{
   convX17.Init(17, pBox->bll.x, pBox->fur.x);
   convY14.Init(14, pBox->bll.y, pBox->fur.y);
   convZ17.Init(17, pBox->bll.z, pBox->fur.z);
   return;
}

/***************************************************************
* _m3dCONV_POS48::ConvPosTo48()
*
* Ranges can be specified on per-level basis
***************************************************************/
template <class _CONV>
void _m3dCONV_POS48<_CONV>::ConvPosTo48 (m3dV *pos, WORD *w1, WORD *w2, WORD *w3)
{
   DWORD    dwX, dwY, dwZ;

   dwX = convX17.ConvInt(pos->x);
   dwY = convY14.ConvInt(pos->y);
   dwZ = convZ17.ConvInt(pos->z);

   *w1 = (WORD)(dwX & 0xFFFF);
   *w2 = (WORD)(dwZ & 0xFFFF);
   *w3 = (WORD)((dwY & 0x3FFF) | ((dwX & 0x10000) >> 2) | ((dwZ & 0x10000) >> 1));
   return;
}

/***************************************************************
* _m3dCONV_POS48::Conv48ToPos()
*
* Ranges can be specified on per-level basis
***************************************************************/
template <class _CONV>
void _m3dCONV_POS48<_CONV>::Conv48ToPos (WORD w1, WORD w2, WORD w3, m3dV *pos)
{
   DWORD    dw;

   dw = w1 | ((w3 & 0x4000) << 2);
   pos->x = convX17.ConvFlt(dw);

   dw = w2 | ((w3 & 0x8000) << 1);
   pos->z = convZ17.ConvFlt(dw);

   dw = (w3 & 0x3FFF);
   pos->y = convY14.ConvFlt(dw);

   return;
}

/***************************************************************
* m3dCONV_POS32::m3dCONV_POS32()
*
***************************************************************/
template <class _CONV>
_m3dCONV_POS32<_CONV>::_m3dCONV_POS32 (void) 
{
   // note - this is NOT a virtual call
   Init();
}

/***************************************************************
* m3dCONV_POS32::Init()
*
***************************************************************/
template <class _CONV>
void _m3dCONV_POS32<_CONV>::Init (void) 
{
   convX11.Init(11, -200.f, 200.f);
   convY10.Init(10, -100.f, 100.f);
   convZ11.Init(11, -200.f, 200.f);
   return;
}

/***************************************************************
* m3dCONV_POS32::Init()
*
***************************************************************/
template <class _CONV>
void _m3dCONV_POS32<_CONV>::Init (m3dBOX *pBox) 
{
   convX11.Init(11, pBox->bll.x, pBox->fur.x);
   convY10.Init(10, pBox->bll.y, pBox->fur.y);
   convZ11.Init(11, pBox->bll.z, pBox->fur.z);
   return;
}

/***************************************************************
* _m3dCONV_POS32::ConvPosTo32()
*
* Ranges can be specified on per-level basis
***************************************************************/
template <class _CONV>
void _m3dCONV_POS32<_CONV>::ConvPosTo32 (m3dV *pos, DWORD *dw)
{
   DWORD    dwX, dwY, dwZ;

   dwX = convX11.ConvInt(pos->x);
   dwY = convY10.ConvInt(pos->y);
   dwZ = convZ11.ConvInt(pos->z);

   *dw = ((dwX & 0x07FF) << 21) | ((dwY & 0x03FF) << 11) | (dwZ & 0x07FF);
   return;
}

/***************************************************************
* _m3dCONV_POS32::Conv32ToPos()
*
* Ranges can be specified on per-level basis
***************************************************************/
template <class _CONV>
void _m3dCONV_POS32<_CONV>::Conv32ToPos (DWORD dw, m3dV *pos)
{
   DWORD    d;

   d = (dw & 0xFFE00000) >> 21;
   pos->x = convX11.ConvFlt(d);

   d = (dw & 0x001FF800) >> 11;
   pos->y = convY10.ConvFlt(d);

   d = (dw & 0x000007FF);
   pos->z = convZ11.ConvFlt(d);

   return;
}


/***************************************************************
* m3dCONV_FAST::Write()
*
***************************************************************/
template <class FILE>
void m3dCONV_FAST::Write(FILE& file) const
{
   file.Write(a);
   file.Write(b);
   file.Write(fa);
   file.Write(fb);
   file.Write(c1_Int);
   file.Write(c2_Int);
   file.Write(c1_Flt);
   file.Write(c2_Flt);
   return;
}
/***************************************************************
* m3dCONV_FAST::Write()
*
***************************************************************/
template <class FILE>
void m3dCONV_FAST::Read(FILE& file)
{
   file.Read(&a);
   file.Read(&b);
   file.Read(&fa);
   file.Read(&fb);
   file.Read(&c1_Int);
   file.Read(&c2_Int);
   file.Read(&c1_Flt);
   file.Read(&c2_Flt);
   return;
}

/***************************************************************
* m3dCONV_TIGHT::Write()
*
***************************************************************/
template <class FILE>
void m3dCONV_TIGHT::Write(FILE& file) const
{
   file.Write(nBit);
   file.Write(aShort);
   file.Write(bShort);
   return;
}
/***************************************************************
* m3dCONV_TIGHT::Write()
*
***************************************************************/
template <class FILE>
void m3dCONV_TIGHT::Read(FILE& file)
{
   file.Read(&nBit);
   file.Read(&aShort);
   file.Read(&bShort);
   return;
}

/***************************************************************
* _m3dCONV_POS48::Write()
*
***************************************************************/
template <class _CONV>
template <class FILE>
void _m3dCONV_POS48<_CONV>::Write(FILE& file) const
{
   convX17.Write(file);
   convY14.Write(file);
   convZ17.Write(file);
   return;
}
/***************************************************************
* _m3dCONV_POS48::Write()
*
***************************************************************/
template <class _CONV>
template <class FILE>
void _m3dCONV_POS48<_CONV>::Read(FILE& file)
{
   convX17.Read(file);
   convY14.Read(file);
   convZ17.Read(file);
   return;
}

/***************************************************************
* _m3dCONV_POS32::Write()
*
***************************************************************/
template <class _CONV>
template <class FILE>
void _m3dCONV_POS32<_CONV>::Write(FILE& file) const
{
   convX11.Write(file);
   convY10.Write(file);
   convZ11.Write(file);
   return;
}
/***************************************************************
* _m3dCONV_POS48::Write()
*
***************************************************************/
template <class _CONV>
template <class FILE>
void _m3dCONV_POS32<_CONV>::Read(FILE& file)
{
   convX11.Read(file);
   convY10.Read(file);
   convZ11.Read(file);
   return;
}


//
// End-of-file M3D_FLOAT2INT.HPP
//
